package pfq.demo.threads;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * Callable、Future、FutureTask
 * Created by pangfuqiang on 2018/6/23.
 */

public class CallableTest {

    public static void main(String[] args) {
        System.out.println("主线程：" + Thread.currentThread().getName());
        // Rannble
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("runnable线程: " + Thread.currentThread().getName());
            }
        };
        new Thread(runnable).start();


        // Thread
        new Thread() {
            @Override
            public void run() {
                System.out.println("thread线程: " + Thread.currentThread().getName());
            }
        }.start();

        // Callable，看名字就知道跟Runnable类似，都是执行异步任务的接口，但区别在于Callable有返回值，并且会抛出异常
        Callable<Long> callable = new Callable<Long>() {
            @Override
            public Long call() throws Exception {
                Thread.sleep(3000);
                return 521L;
            }
        };
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        // Future，和Callable是对应使用的，因为Callable的结果是通过Future获取的，并且还能控制Callable的执行与取消
        Future<Long> future = executorService.submit(callable);
        if (!future.isDone()) {
            System.out.println("Callable任务还没有结束");
        }
        System.out.println("暂时不用Callable的结果");
        try {
            Long callableResult = future.get();
            System.out.println("Callable的结果是：" + callableResult);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("======================");


        // FutureTask, 实现了Runnable、Future接口，还可以通过构造函数接收一个Callable，也就是说FutureTask既可以是Callable+Future，又可以是Runnable
        // Runnable是可以交给Thread去执行的，而Callable是不行的，但有了FutureTask就可以将Callable间接的交给Thread
        FutureTask<Long> futureTask = new FutureTask<>(callable);
        new Thread(futureTask).start();
        System.out.println("暂时不用FutureTask的结果");
        try {
            Long callableResult = futureTask.get();
            System.out.println("FutureTask的结果是：" + callableResult);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}
